#include <sys/types.h>
#include <sys/wait.h>
#include "shmem.h"
#include "msg_queue_peer.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <curl/curl.h>
#include "cJSON.h"
#include "MQTTClient.h"
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <ctype.h>

// 定义最大节点数量
#define MAX_NODES 100

// Add function prototype
int init_server(int port);

#define ADDRESS "tcp://localhost:8080"
#define CLIENTID "ExampleClientPub"
#define TOPIC "sensor/data/#"
#define QOS 1
#define TIMEOUT 10000L
#define PRINT_INTERVAL 5 // 定时打印间隔，单位：秒

// 定义设备 key 映射
#define KEY_LED 305
#define KEY_FAN 306
#define KEY_SMOKE 101
#define KEY_WINDOW_SWITCH 102

int sockfd;            // 定义文件描述符
struct shm_param para; // 共享内存的首地址
int *total;            // 指向共享内存中数据节点总个数
data_t *node_arr;      // 指向共享内存中节点缓存数组头
void *node_p;
void set_slave_id(uint8_t *p, int id) // 设置从机id
{
    *(p + 6) = id;
}

// 读保持寄存器      （发送数据首地址，  功能码，   寄存器地址，寄存器数量，存放接受数据首地址）
void read_registers(uint8_t *p, int function, int addr, int nb, uint8_t *dest)
{
    int i;
    *(p + 5) = 6;              // 后面字节数
    *(p + 7) = (char)function; // 功能码
    *(p + 8) = addr >> 8;      // 寄存器高字节地址
    *(p + 9) = addr & 0xff;    // 寄存器低字节地址
    *(p + 10) = nb >> 8;       // 寄存器数量高位
    *(p + 11) = nb & 0xff;     // 寄存器数量低位

    send(sockfd, p, 12, 0); // 注意这里不能sizeof(p),p为指针

    recv(sockfd, dest, 64, 0); // 注意这里不能sizeof(dest),dest为指针
}

void write_coil(uint8_t *p, int function, int addr, int nb, uint8_t *dest)
{
    int i = 0;
    *(p + 5) = 6;              // 后面字节数
    *(p + 7) = (char)function; // 功能码
    *(p + 8) = addr >> 8;      // 线圈高位地址
    *(p + 9) = addr & 0xff;    // 线圈低位地址
    if (nb == 1)
        *(p + 10) = 0xff;
    else if (nb == 0)
        *(p + 10) = 0x00;
    *(p + 11) = 0x00;

    send(sockfd, p, 12, 0);

    recv(sockfd, dest, 64, 0);
}

// 读取输入寄存器函数
void read_input_registers(uint8_t *p, int function, int addr, int nb, uint8_t *dest)
{
    int i;
    *(p + 5) = 6;              // 后面字节数
    *(p + 7) = (char)function; // 功能码
    *(p + 8) = addr >> 8;      // 寄存器高字节地址
    *(p + 9) = addr & 0xff;    // 寄存器低字节地址
    *(p + 10) = nb >> 8;       // 寄存器数量高位
    *(p + 11) = nb & 0xff;     // 寄存器数量低位

    send(sockfd, p, 12, 0);    // 发送请求
    recv(sockfd, dest, 64, 0); // 接收响应
}

// 将十六进制字符串转换为十进制整数
long long hex_to_decimal(const char *hex_str)
{
    long long result = 0;
    size_t len = strlen(hex_str);

    // 跳过可能的 "0x" 或 "0X" 前缀
    if (len >= 2 && hex_str[0] == '0' && (hex_str[1] == 'x' || hex_str[1] == 'X'))
    {
        hex_str += 2;
        len -= 2;
    }

    for (size_t i = 0; i < len; i++)
    {
        char c = toupper(hex_str[i]);
        if (c >= '0' && c <= '9')
        {
            result = result * 16 + (c - '0');
        }
        else if (c >= 'A' && c <= 'F')
        {
            result = result * 16 + (c - 'A' + 10);
        }
        else
        {
            // 遇到非十六进制字符，返回 0
            return 0;
        }
    }
    return result;
}

// 定义读取线圈的函数
void read_coils(uint8_t *p, int function, int addr, int nb, uint8_t *dest)
{
    int i;
    *(p + 5) = 6;              // 后面字节数
    *(p + 7) = (char)function; // 功能码
    *(p + 8) = addr >> 8;      // 线圈高位地址
    *(p + 9) = addr & 0xff;    // 线圈低位地址
    *(p + 10) = nb >> 8;       // 线圈数量高位
    *(p + 11) = nb & 0xff;     // 线圈数量低位

    send(sockfd, p, 12, 0);
    recv(sockfd, dest, 64, 0);
}

// 从 node.json 读取设备节点信息
int read_device_nodes(const char *filename, data_t *node_arr, int *total)
{
    FILE *fp = fopen(filename, "r");
    if (fp == NULL)
    {
        perror("Failed to open node.json");
        return -1;
    }

    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    char *buffer = (char *)malloc(size + 1);
    if (buffer == NULL)
    {
        perror("Failed to allocate memory");
        fclose(fp);
        return -1;
    }

    fread(buffer, 1, size, fp);
    buffer[size] = '\0';
    fclose(fp);

    cJSON *root = cJSON_Parse(buffer);
    if (root == NULL)
    {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL)
        {
            fprintf(stderr, "Error before: %s\n", error_ptr);
        }
        free(buffer);
        return -1;
    }

    cJSON *stm32_data = cJSON_GetObjectItem(cJSON_GetObjectItem(root, "stm32"), "data");
    cJSON *modbus_data = cJSON_GetObjectItem(cJSON_GetObjectItem(root, "modbus"), "data");
    if (!stm32_data || !modbus_data)
    {
        fprintf(stderr, "stm32 or modbus data not found in node.json\n");
        cJSON_Delete(root);
        free(buffer);
        return -1;
    }
    int stm32_count = cJSON_GetArraySize(stm32_data);
    int modbus_count = cJSON_GetArraySize(modbus_data);
    *total = stm32_count + modbus_count;

    int index = 0;
    for (int i = 0; i < stm32_count; i++)
    {
        cJSON *item = cJSON_GetArrayItem(stm32_data, i);
        if (item)
        {
            cJSON *key_json = cJSON_GetObjectItem(item, "key");
            cJSON *type_json = cJSON_GetObjectItem(item, "type");
            // 新增解析 slave_addr 和 addr，若 stm32 节点没有，可设为默认值
            cJSON *slave_addr_json = cJSON_GetObjectItem(item, "slave_addr");
            cJSON *addr_json = cJSON_GetObjectItem(item, "addr");
            if (cJSON_IsNumber(key_json) && cJSON_IsNumber(type_json))
            {
                node_arr[index].key = key_json->valueint;
                node_arr[index].type = type_json->valueint;
                node_arr[index].slave_addr = cJSON_IsNumber(slave_addr_json) ? slave_addr_json->valueint : 0;
                node_arr[index].addr = cJSON_IsNumber(addr_json) ? addr_json->valueint : 0;
                printf("Loaded stm32 node: key = %d, type = %d, slave_addr = %d, addr = %d\n",
                       node_arr[index].key, node_arr[index].type, node_arr[index].slave_addr, node_arr[index].addr);
                index++;
            }
            else
            {
                fprintf(stderr, "Invalid stm32 node data at index %d\n", i);
            }
        }
    }
    for (int i = 0; i < modbus_count; i++)
    {
        cJSON *item = cJSON_GetArrayItem(modbus_data, i);
        if (item)
        {
            cJSON *key_json = cJSON_GetObjectItem(item, "key");
            cJSON *type_json = cJSON_GetObjectItem(item, "type");
            cJSON *slave_addr_json = cJSON_GetObjectItem(item, "slave_addr");
            cJSON *addr_json = cJSON_GetObjectItem(item, "addr");
            if (cJSON_IsNumber(key_json) && cJSON_IsNumber(type_json) &&
                cJSON_IsNumber(slave_addr_json) && cJSON_IsNumber(addr_json))
            {
                node_arr[index].key = key_json->valueint;
                node_arr[index].type = type_json->valueint;
                node_arr[index].slave_addr = slave_addr_json->valueint;
                node_arr[index].addr = addr_json->valueint;
                printf("Loaded modbus node: key = %d, type = %d, slave_addr = %d, addr = %d\n",
                       node_arr[index].key, node_arr[index].type, node_arr[index].slave_addr, node_arr[index].addr);
                index++;
            }
            else
            {
                fprintf(stderr, "Invalid modbus node data at index %d\n", i);
            }
        }
    }

    cJSON_Delete(root);
    free(buffer);
    return 0;
}

// 打印共享内存中各模块状态
void print_module_states()
{
    printf("=== 共享内存模块状态 ===\n");
    for (int i = 0; i < *total; i++)
    {
        printf("Key: %d, ", node_arr[i].key);
        switch (node_arr[i].type)
        {
        case 1:
            printf("State: %d\n", node_arr[i].new_val.b_val);
            break;
        case 3:
            printf("Value: %.2f\n", node_arr[i].new_val.f_val);
            break;
        default:
            printf("Unknown type\n");
            break;
        }
    }
    printf("=======================\n");
}

// 定时打印共享内存数据的线程函数
static void *print_shm_data_periodically(void *arg)
{
    pthread_detach(pthread_self());
    while (1)
    {
        sleep(PRINT_INTERVAL);
        if (total != NULL && node_arr != NULL)
        {
            print_module_states();
        }
    }
    return NULL;
}

// 处理设备控制请求
void handle_control_request(int sock, const char *request_body)
{
    cJSON *root = cJSON_Parse(request_body);
    if (root == NULL)
    {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL)
        {
            fprintf(stderr, "Error before: %s\n", error_ptr);
        }
        // 构造包含 CORS 头的错误响应
        const char *response_template = "HTTP/1.1 400 Bad Request\r\n"
                                        "Access-Control-Allow-Origin: *\r\n"
                                        "Access-Control-Allow-Methods: POST\r\n"
                                        "Access-Control-Allow-Headers: Content-Type\r\n"
                                        "Content-Type: application/json\r\n"
                                        "Content-Length: %zu\r\n"
                                        "\r\n"
                                        "%s";
        char response[1024];
        const char *error_msg = "{\"message\": \"请求解析失败\"}";
        snprintf(response, sizeof(response), response_template, strlen(error_msg), error_msg);
        send(sock, response, strlen(response), 0);
        return;
    }

    cJSON *key_json = cJSON_GetObjectItem(root, "key");
    cJSON *state_json = cJSON_GetObjectItem(root, "state");
    if (cJSON_IsNumber(key_json) && cJSON_IsNumber(state_json))
    {
        int key = key_json->valueint;
        int state = state_json->valueint;

        // 判断是否为开窗或关窗操作
        if (key == KEY_WINDOW_SWITCH)
        {
            struct sockaddr_in s;

            uint8_t data[12] = {0};
            uint8_t dest[64] = {0};
            int i;

            // 1.socket创建套接字
            sockfd = socket(AF_INET, SOCK_STREAM, 0);
            if (sockfd < 0)
            {
                perror("socket err");
                return -1;
            }

            socklen_t len = sizeof(struct sockaddr_in);

            // 2.填充结构体
            s.sin_family = AF_INET;          // 协议族
            s.sin_port = htons(atoi("502")); // htons:小端转大端 atoi:将数字字符串转换为数值

            s.sin_addr.s_addr = inet_addr("192.168.50.207"); // 字符串转点分十进制

            // 3.connect请求连接
            if (connect(sockfd, (struct sockaddr *)&s, len) < 0)
            {
                perror("connect err");
                return -1;
            }

            // 4.设置从机ID
            set_slave_id(data, 1);
            printf("从机id\n");
            if(state == 1)
            {
                // 开窗操作
                write_coil(data, 0x05, 0, 1, dest); // 线圈置一
            }
            else if(state == 0)
            {
                // 关窗操作
                write_coil(data, 0x05, 0, 0, dest); // 线圈置零
            }
            else
            {
                printf("无效的开关状态: %d\n", state);
                close(sockfd);
                return;
            }
            // 5.关闭套接字
            close(sockfd);
        }

        // 遍历共享内存节点，找到对应 key 并更新数据
        for (int i = 0; i < *total; i++)
        {
            if (node_arr[i].key == key)
            {
                node_arr[i].new_val.b_val = state;
                node_arr[i].ret = 0; // 标记更新成功
                // 构造包含 CORS 头的成功响应
                const char *response_template = "HTTP/1.1 200 OK\r\n"
                                                "Access-Control-Allow-Origin: *\r\n"
                                                "Access-Control-Allow-Methods: POST\r\n"
                                                "Access-Control-Allow-Headers: Content-Type\r\n"
                                                "Content-Type: application/json\r\n"
                                                "Content-Length: %zu\r\n"
                                                "\r\n"
                                                "%s";
                char response[1024];
                const char *success_msg = "{\"message\": \"共享内存更新成功\"}";
                snprintf(response, sizeof(response), response_template, strlen(success_msg), success_msg);
                send(sock, response, strlen(response), 0);
                // 打印更新后的状态
                print_module_states();
                break;
            }
        }
    }
    else
    {
        // 构造包含 CORS 头的参数错误响应
        const char *response_template = "HTTP/1.1 400 Bad Request\r\n"
                                        "Access-Control-Allow-Origin: *\r\n"
                                        "Access-Control-Allow-Methods: POST\r\n"
                                        "Access-Control-Allow-Headers: Content-Type\r\n"
                                        "Content-Type: application/json\r\n"
                                        "Content-Length: %zu\r\n"
                                        "\r\n"
                                        "%s";
        char response[1024];
        const char *param_error_msg = "{\"message\": \"请求参数错误\"}";
        snprintf(response, sizeof(response), response_template, strlen(param_error_msg), param_error_msg);
        send(sock, response, strlen(response), 0);
    }

    cJSON_Delete(root);
}

// 线程处理函数，并设置为非阻塞，自动回收线程资源
void send_response_with_cors(int sock, const char *status, const char *content_type, const char *body)
{
    const char *response_template = "%s\r\n"
                                    "Access-Control-Allow-Origin: *\r\n"
                                    "Access-Control-Allow-Methods: GET, POST, OPTIONS\r\n"
                                    "Access-Control-Allow-Headers: Content-Type\r\n"
                                    "Access-Control-Max-Age: 86400\r\n"
                                    "Content-Type: %s\r\n"
                                    "Content-Length: %zu\r\n"
                                    "\r\n"
                                    "%s";
    char response[4096];
    snprintf(response, sizeof(response), response_template, status, content_type, strlen(body), body);
    send(sock, response, strlen(response), 0);
}

// 线程处理函数，并设置为非阻塞，自动回收线程资源
static void *msg_request(void *arg)
{
    int sock = *((int *)arg);
    pthread_detach(pthread_self());
    printf("进入线程函数，sock = %d\n", sock);

    char buffer[1024] = {0};
    ssize_t bytes_received = recv(sock, buffer, sizeof(buffer) - 1, 0);
    if (bytes_received > 0)
    {
        printf("接收到请求:\n%s\n", buffer);
        // 检查是否为 OPTIONS 请求
        if (strstr(buffer, "OPTIONS") != NULL)
        {
            // 构造包含 CORS 头的 OPTIONS 响应
            const char *response_template = "HTTP/1.1 200 OK\r\n"
                                            "Access-Control-Allow-Origin: *\r\n"
                                            "Access-Control-Allow-Methods: GET, POST, OPTIONS\r\n"
                                            "Access-Control-Allow-Headers: Content-Type\r\n"
                                            "Access-Control-Max-Age: 86400\r\n"
                                            "Content-Length: 0\r\n"
                                            "\r\n";
            send(sock, response_template, strlen(response_template), 0);
        }
        else if (strstr(buffer, "POST /api/control") != NULL || strstr(buffer, "POST /api/data") != NULL)
        {
            // 提取请求体
            char *body_start = strstr(buffer, "\r\n\r\n");
            if (body_start != NULL)
            {
                body_start += 4;
                if (strstr(buffer, "POST /api/control") != NULL)
                {
                    printf("处理控制请求，请求体: %s\n", body_start);
                    handle_control_request(sock, body_start);
                }
                else if (strstr(buffer, "POST /api/data") != NULL)
                {
                    printf("处理数据请求，请求体: %s\n", body_start);
                    handle_data_request(sock, body_start);
                }
            }
        }
        else
        {
            // 处理静态资源请求，比如 CSS、JavaScript 等
            const char *error_body = "";
            send_response_with_cors(sock, "HTTP/1.1 404 Not Found", "text/plain", error_body);
        }
    }
    else
    {
        printf("未接收到有效请求数据，错误码: %zd\n", bytes_received);
    }

    close(sock);
    free(arg);
    return NULL;
}

// 定义设备 key 映射
#define KEY_LED 305
#define KEY_FAN 306
#define KEY_SMOKE 101
#define KEY_WINDOW_SWITCH 102

// 处理数据请求函数
void handle_data_request(int sock, const char *request_body)
{
    print_module_states();
    cJSON *root = cJSON_CreateObject();
    if (total != NULL && node_arr != NULL && *total > 0)
    {
        printf("Number of nodes in shared memory: %d\n", *total);
        for (int i = 0; i < *total; i++)
        {
            printf("Current node key: %d, type: %d\n", node_arr[i].key, node_arr[i].type);
            switch (node_arr[i].key)
            {
            case 301:
                cJSON_AddNumberToObject(root, "temperature", node_arr[i].new_val.f_val);
                break;
            case 302:
                cJSON_AddNumberToObject(root, "humidity", node_arr[i].new_val.f_val);
                break;
            case 303:
                cJSON_AddNumberToObject(root, "light", node_arr[i].new_val.f_val);
                break;
            case 304:
                cJSON_AddNumberToObject(root, "fire", node_arr[i].new_val.b_val);
                break;
            case 305:
                cJSON_AddNumberToObject(root, "led", node_arr[i].new_val.b_val);
                break;
            case 306:
                cJSON_AddNumberToObject(root, "fan", node_arr[i].new_val.b_val);
                break;
            case 101:
                cJSON_AddNumberToObject(root, "smoke", node_arr[i].new_val.f_val);
                break;
            case 102:
                cJSON_AddNumberToObject(root, "window_switch", node_arr[i].new_val.b_val);
                break;
            default:
                break;
            }
        }
    }
    else
    {
        printf("Shared memory data is empty or not initialized correctly, total = %d\n", *total);
        // 添加默认值
        cJSON_AddNumberToObject(root, "led", 0);
        cJSON_AddNumberToObject(root, "fan", 0.0);
        cJSON_AddNumberToObject(root, "smoke", 0.0);
        cJSON_AddNumberToObject(root, "window_switch", 0);
    }

    char *response_str = cJSON_Print(root);
    printf("Data returned to the frontend: %s\n", response_str);
    send_response_with_cors(sock, "HTTP/1.1 200 OK", "application/json", response_str);
    cJSON_Delete(root);
}

// MQTT 消息处理回调函数
int message_arrived(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    char *payload = (char *)message->payload;
    int type1, key, type2;
    float value;

    printf("收到 MQTT 消息: %s\n", payload);
    // 解析以空格分隔的消息
    if (sscanf(payload, "%d %d %d %f", &type1, &key, &type2, &value) == 4)
    {
        printf("MQTT 消息解析成功: type1 = %d, key = %d, type2 = %d, value = %f\n", type1, key, type2, value);
        // 遍历共享内存节点，找到对应 key 并更新数据
        for (int i = 0; i < *total; i++)
        {
            if (node_arr[i].key == key)
            {
                switch (type2)
                {
                case 1:
                    node_arr[i].new_val.b_val = (int)value;
                    break;
                case 3:
                    node_arr[i].new_val.f_val = value;
                    break;
                default:
                    break;
                }
                node_arr[i].ret = 0; // 标记采集成功
                printf("共享内存节点 %d 更新成功\n", key);
                break;
            }
        }
    }
    else
    {
        printf("MQTT 消息解析失败: %s\n", payload);
    }

    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}

// 连接 MQTT 服务器并订阅主题
int connect_mqtt(const char *addr, int port)
{
    char mqtt_address[100];
    snprintf(mqtt_address, sizeof(mqtt_address), "tcp://%s:%d", addr, port);

    MQTTClient client;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    int rc;

    MQTTClient_create(&client, mqtt_address, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;

    MQTTClient_setCallbacks(client, NULL, NULL, message_arrived, NULL);

    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        return -1;
    }
    printf("Connected to MQTT server %s:%d\n", addr, port);

    if ((rc = MQTTClient_subscribe(client, TOPIC, QOS)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to subscribe, return code %d\n", rc);
        MQTTClient_disconnect(client, 10000);
        MQTTClient_destroy(&client);
        return -1;
    }

    // 保持 MQTT 连接
    while (1)
    {
        MQTTClient_yield();
    }

    MQTTClient_disconnect(client, 10000);
    MQTTClient_destroy(&client);
    return rc;
}

/**
 * 这里是主函数
 * 可以用命令行参数自定义端口号
 */
#include <sys/msg.h>

// 定义消息队列结构体
#define MSG_KEY 1234
#define MAX_MSG_SIZE 1024

typedef struct
{
    long mtype;
    char mtext[MAX_MSG_SIZE];
} Message;

// 消息队列消息处理函数
void *msg_queue_handler(void *arg)
{
    int msqid = msgget(MSG_KEY, 0666 | IPC_CREAT);
    if (msqid == -1)
    {
        perror("msgget failed");
        return NULL;
    }

    Message msg;
    while (1)
    {
        if (msgrcv(msqid, &msg, MAX_MSG_SIZE, 1, 0) == -1)
        {
            perror("msgrcv failed");
            continue;
        }

        char *payload = msg.mtext;
        int type1, key, type2;
        float value;

        printf("收到消息队列消息: %s\n", payload);
        // 解析以空格分隔的消息
        if (sscanf(payload, "%d %d %d %f", &type1, &key, &type2, &value) == 4)
        {
            printf("消息队列消息解析成功: type1 = %d, key = %d, type2 = %d, value = %f\n", type1, key, type2, value);
            // 遍历共享内存节点，找到对应 key 并更新数据
            for (int i = 0; i < *total; i++)
            {
                if (node_arr[i].key == key)
                {
                    switch (type2)
                    {
                    case 1:
                        node_arr[i].new_val.b_val = (int)value;
                        break;
                    case 3:
                        node_arr[i].new_val.f_val = value;
                        break;
                    default:
                        break;
                    }
                    node_arr[i].ret = 0; // 标记采集成功
                    printf("共享内存节点 %d 更新成功\n", key);
                    break;
                }
            }
        }
        else
        {
            printf("消息队列消息解析失败: %s\n", payload);
        }
    }
    return NULL;
}

// 从 node.json 读取 MQTT 服务器信息
int read_mqtt_info(const char *filename, char *addr, int *port)
{
    FILE *fp = fopen(filename, "r");
    if (fp == NULL)
    {
        perror("Failed to open node.json");
        return -1;
    }

    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    char *buffer = (char *)malloc(size + 1);
    if (buffer == NULL)
    {
        perror("Failed to allocate memory");
        fclose(fp);
        return -1;
    }

    fread(buffer, 1, size, fp);
    buffer[size] = '\0';
    fclose(fp);

    cJSON *root = cJSON_Parse(buffer);
    if (root == NULL)
    {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL)
        {
            fprintf(stderr, "Error before: %s\n", error_ptr);
        }
        free(buffer);
        return -1;
    }

    cJSON *mb_dev = cJSON_GetObjectItem(root, "mb_dev");
    if (cJSON_IsObject(mb_dev))
    {
        cJSON *mb_addr = cJSON_GetObjectItem(mb_dev, "addr");
        cJSON *mb_port = cJSON_GetObjectItem(mb_dev, "port");
        if (cJSON_IsString(mb_addr) && cJSON_IsNumber(mb_port))
        {
            strcpy(addr, mb_addr->valuestring);
            *port = mb_port->valueint;
        }
        else
        {
            cJSON_Delete(root);
            free(buffer);
            return -1;
        }
    }
    else
    {
        cJSON_Delete(root);
        free(buffer);
        return -1;
    }

    cJSON_Delete(root);
    free(buffer);
    return 0;
}

// 读取 Modbus 数据并存入共享内存的线程函数
static void *read_modbus_data(void *arg)
{
    char mb_addr[100];
    int mb_port;
    if (read_modbus_info("node.json", mb_addr, &mb_port) != 0)
    {
        printf("Failed to read Modbus info from node.json\n");
        return NULL;
    }

    struct sockaddr_in s;
    uint8_t data[12] = {0};
    uint8_t dest[64] = {0};

    // 1.socket创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket err");
        return NULL;
    }

    socklen_t len = sizeof(struct sockaddr_in);

    // 2.填充结构体
    s.sin_family = AF_INET;
    s.sin_port = htons(mb_port);
    s.sin_addr.s_addr = inet_addr(mb_addr);

    // 3.connect请求连接
    if (connect(sockfd, (struct sockaddr *)&s, len) < 0)
    {
        perror("connect err");
        close(sockfd);
        return NULL;
    }

    while (1)
    {
        // 设置从机ID
        set_slave_id(data, 102);
        // 使用功能码 0x01 读取 1 个线圈状态
        read_coils(data, 0x01, 0, 1, dest);

        char coil_hex_str[128] = {0};
        for (int i = 0; i < dest[8]; i++)
        {
            sprintf(coil_hex_str + strlen(coil_hex_str), "%02x", dest[9 + i]);
        }
        long long coil_decimal = hex_to_decimal(coil_hex_str);

        // 假设共享内存中有对应 key 为 102 的线圈节点
        for (int i = 0; i < *total; i++)
        {
            if (node_arr[i].key == 102)
            {
                node_arr[i].new_val.b_val = (int)coil_decimal;
                node_arr[i].ret = 0; // 标记更新成功
                break;
            }
        }

        // 设置从机 ID 为 101 读取输入寄存器
        set_slave_id(data, 101);
        // 使用功能码 0x04 读取 1 个输入寄存器
        read_input_registers(data, 0x04, 0, 1, dest);

        char input_reg_hex_str[128] = {0};
        for (int i = 0; i < dest[8]; i++)
        {
            sprintf(input_reg_hex_str + strlen(input_reg_hex_str), "%02x", dest[9 + i]);
        }
        long long input_reg_decimal = hex_to_decimal(input_reg_hex_str);

        // 假设共享内存中有对应 key 为 101 的输入寄存器节点
        for (int i = 0; i < *total; i++)
        {
            if (node_arr[i].key == 101)
            {
                node_arr[i].new_val.f_val = (float)input_reg_decimal;
                node_arr[i].ret = 0; // 标记更新成功
                break;
            }
        }

        sleep(1);
    }

    close(sockfd);
    return NULL;
}

int main(int argc, char *argv[])
{
    printf("开始运行.............\n");
    int ret = -1;

    ret = shm_init(&para, "222.c", MAX_NODES);
    if (ret < 0)
    {
        printf("共享内存初始化失败\n");
        return -1;
    }

    node_p = shm_getaddr(&para);
    if (node_p == NULL)
    {
        printf("共享内存地址获取失败\n");
        return -1;
    }
    printf("创建共享内存成功！\n");

    total = (int *)node_p;
    node_arr = (data_t *)((char *)node_p + sizeof(int));

    // 从 node.json 读取设备节点信息
    if (read_device_nodes("node.json", node_arr, total) != 0)
    {
        printf("Failed to read device nodes from node.json\n");
        return -1;
    }

    printf("共享内存节点数量: %d\n", *total);

    // 修改为非特权端口
    int port = 8080;
    if (argc > 1)
    {
        port = atoi(argv[1]);
    }
    int lis_sock = init_server(port);

    // 创建定时打印共享内存数据的线程
    pthread_t print_thread;
    if (pthread_create(&print_thread, NULL, print_shm_data_periodically, NULL) != 0)
    {
        perror("Failed to create print thread");
    }

    // 读取 MQTT 信息并连接
    char mqtt_addr[100];
    int mqtt_port;
    if (read_mqtt_info("node.json", mqtt_addr, &mqtt_port) == 0)
    {
        // 创建线程处理 MQTT 连接
        pthread_t mqtt_thread;
        if (pthread_create(&mqtt_thread, NULL, (void *(*)(void *))connect_mqtt, (void *)&mqtt_port) != 0)
        {
            perror("Failed to create MQTT thread");
        }
    }
    else
    {
        printf("Failed to read MQTT info from node.json\n");
    }

    // 创建线程读取 Modbus 数据
    pthread_t modbus_thread;
    if (pthread_create(&modbus_thread, NULL, read_modbus_data, NULL) != 0)
    {
        perror("Failed to create Modbus thread");
    }

    while (1)
    {
        struct sockaddr_in peer;
        socklen_t len = sizeof(peer);
        int sock = accept(lis_sock, (struct sockaddr *)&peer, &len);
        if (sock < 0)
        {
            perror("accept failed");
            continue;
        }

        int *new_sock = malloc(sizeof(int));
        if (new_sock == NULL)
        {
            perror("malloc failed");
            close(sock);
            continue;
        }
        *new_sock = sock;

        pthread_t tid;
        if (pthread_create(&tid, NULL, msg_request, (void *)new_sock) > 0)
        {
            perror("pthread_create failed");
            close(sock);
            free(new_sock);
        }
        else
        {
            printf("创建线程成功，sock = %d\n", sock);
        }
    }

    return 0;
}

// 从 node.json 读取 Modbus 设备信息
int read_modbus_info(const char *filename, char *addr, int *port)
{
    FILE *fp = fopen(filename, "r");
    if (fp == NULL)
    {
        perror("Failed to open node.json");
        return -1;
    }

    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    char *buffer = (char *)malloc(size + 1);
    if (buffer == NULL)
    {
        perror("Failed to allocate memory");
        fclose(fp);
        return -1;
    }

    fread(buffer, 1, size, fp);
    buffer[size] = '\0';
    fclose(fp);

    cJSON *root = cJSON_Parse(buffer);
    if (root == NULL)
    {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL)
        {
            fprintf(stderr, "Error before: %s\n", error_ptr);
        }
        free(buffer);
        return -1;
    }

    // 获取 mb_dev 节点
    cJSON *mb_dev = cJSON_GetObjectItem(root, "mb_dev");
    if (mb_dev == NULL || !cJSON_IsObject(mb_dev))
    {
        fprintf(stderr, "mb_dev not found in JSON\n");
        cJSON_Delete(root);
        free(buffer);
        return -1;
    }

    // 获取 addr 字段
    cJSON *mb_addr = cJSON_GetObjectItem(mb_dev, "addr");
    if (mb_addr == NULL || !cJSON_IsString(mb_addr))
    {
        fprintf(stderr, "mb_dev addr not found or invalid in JSON\n");
        cJSON_Delete(root);
        free(buffer);
        return -1;
    }

    // 获取 port 字段
    cJSON *mb_port = cJSON_GetObjectItem(mb_dev, "port");
    if (mb_port == NULL || !cJSON_IsNumber(mb_port))
    {
        fprintf(stderr, "mb_dev port not found or invalid in JSON\n");
        cJSON_Delete(root);
        free(buffer);
        return -1;
    }

    // 复制地址和端口信息
    strcpy(addr, mb_addr->valuestring);
    *port = mb_port->valueint;

    cJSON_Delete(root);
    free(buffer);
    return 0;
}
